import type {AxiosError, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig,} from "axios";
import axios from "axios";
import {STORAGE_AUTHORIZATION_KEY} from "~/composables/authorization.ts";
import type {ResponseBody} from "~/utils/result";
import i18n from "~/locales";
import router from "~/router";

/**
 * @FileName: request.ts
 * @Description: // axios工具
 * @Author: Ellwood(liugangsin@qq.com)
 * @CreateDate: 2025/2/7 - 14:14
 * @Version: V1.0.0
 */

const instance = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API || "/",
  timeout: 6000,
});

/**
 * 请求拦截
 * @param config 配置
 */
const requestHandler = async (
  config: InternalAxiosRequestConfig,
): Promise<InternalAxiosRequestConfig> => {
  const token = useAuthorization();
  if (token.value) {
    config.headers.set(STORAGE_AUTHORIZATION_KEY, token.value);
  }

  return config;
};

/**
 * 响应拦截
 * @param response 响应
 */
const responseHandler = (
  response: any,
): ResponseBody<any> | AxiosResponse<any> | Promise<any> | any => {
  return response.data;
};

/**
 * 错误
 * @param error 错误参数
 */
const errorHandler = (error: AxiosError): Promise<any> => {
  const { notification } = useGlobalConfig();
  const token = useAuthorization();

  if (error.response) {
    const { data, status, statusText } =
      error.response as AxiosResponse<ResponseBody>;
    if (status === 401) {
      notification?.error({
        title: i18n.global.t("global.request.error.401"),
        content: data?.msg || statusText,
        duration: 3000,
      });

      // 处理清空用户信息和token逻辑，后续再进行扩展
      token.value = null;

      router
        .replace({
          path: "/login",
          query: { redirect: router.currentRoute.value.path },
        })
        .then(() => {});
    } else if (status === 403) {
      notification?.error({
        title: i18n.global.t("global.request.error.403"),
        content: data?.msg || statusText,
        duration: 3000,
      });
    } else if (status === 500) {
      notification?.error({
        title: i18n.global.t("global.request.error.500"),
        content: data?.msg || statusText,
        duration: 3000,
      });
    } else {
      notification?.error({
        title: i18n.global.t("global.request.error.other"),
        content: data?.msg || statusText,
        duration: 3000,
      });
    }
  }

  return Promise.reject(error);
};

instance.interceptors.request.use(requestHandler);
instance.interceptors.response.use(responseHandler, errorHandler);

export default instance;

/**
 * 查询
 * @param url 请求地址
 * @param params 请求参数
 * @param config 配置参数信息
 */
export const useGet = <T = any, R = any>(
  url: string,
  params?: T,
  config?: AxiosRequestConfig,
): Promise<ResponseBody<R>> => {
  return instance.request({
    url,
    params,
    method: "GET",
    ...config,
  });
};

/**
 * 新增
 * @param url 请求地址
 * @param data 数据信息
 * @param config 配置参数信息
 */
export const usePost = <T = any, R = any>(
  url: string,
  data?: T,
  config?: AxiosRequestConfig,
): Promise<ResponseBody<R>> => {
  return instance.request({
    url,
    data,
    method: "POST",
    ...config,
  });
};

/**
 * 更新
 * @param url 请求地址
 * @param data 数据信息
 * @param config 配置参数信息
 */
export const usePut = <T = any, R = any>(
  url: string,
  data?: T,
  config?: AxiosRequestConfig,
): Promise<ResponseBody<R>> => {
  return instance.request({
    url,
    data,
    method: "PUT",
    ...config,
  });
};

/**
 * 删除
 * @param url 请求地址
 * @param data 数据信息
 * @param config 配置参数信息
 */
export const useDelete = <T = any, R = any>(
  url: string,
  data?: T,
  config?: AxiosRequestConfig,
): Promise<ResponseBody<R>> => {
  return instance.request({
    url,
    data,
    method: "DELETE",
    ...config,
  });
};
